package net.jeeshop.web.action.front.paygate;

import net.jeeshop.core.Overall;
import net.jeeshop.core.front.SystemManager;
import net.jeeshop.core.pay.IPay;
import net.jeeshop.core.pay.PayFactory;
import net.jeeshop.core.pay.overall.OverallConfig;
import net.jeeshop.core.pay.wxpay.config.ConstantPool;
import net.jeeshop.core.pay.wxpay.config.WXSign;
import net.jeeshop.core.pay.wxpay.entity.WXPayResult;
import net.jeeshop.core.pay.wxpay.util.QrcodeUtil;
import net.jeeshop.core.pay.wxpay.util.WXPayResultHandle;

import net.jeeshop.services.front.order.OrderService;
import net.jeeshop.services.front.order.bean.Order;
import net.jeeshop.services.front.orderpay.OrderpayService;
import net.jeeshop.services.front.orderpay.bean.Orderpay;
import net.jeeshop.services.front.ordership.OrdershipService;
import net.jeeshop.services.front.ordership.bean.Ordership;
import net.jeeshop.web.util.RequestHolder;
import net.jeeshop.web.util.ResponseUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

/**
 * @author dylan
 * @date 16/2/18 22:58
 * Email: dinguangx@163.com
 */
@Controller("frontPaygateAction")
@RequestMapping("paygate")
public class PaygateAction {

    private final String wxpay= "/wxpay_";
    private final String alipay = "/alipay";
//    private final String notification = "/paySuccess";
    private final String notification = "/paySuccess";
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    SystemManager systemManager;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrdershipService ordershipService;
    @Autowired
    private OrderpayService orderpayService;

    @RequestMapping("pay")
    public String pay(String orderId, String orderPayId,  ModelMap modelMap) {
        Order order = orderService.selectById(orderId);

        if(order == null) {
            throw new NullPointerException("根据订单号查询不到订单信息！");
        }

        Ordership ordership = ordershipService.selectOne(new Ordership(orderId));
        if(ordership==null){
            throw new NullPointerException("根据订单号查询不到配送信息！");
        }
//        net.jeeshop.services.front.orderpay.bean.Orderpay orderpay = orderpayService.selectById(orderPayId);
//        if(orderpay==null){
//            throw new NullPointerException("根据订单号查询不到配送信息！");
//        }
        order.setOrderpayID(orderPayId);
        PayInfo payInfo = createPayInfo(order,ordership);
//        RequestHolder.getRequest().setAttribute("payInfo", payInfo);
        modelMap.addAttribute("payInfo", payInfo);
        ///使用的网关
        String paygateType = systemManager.getProperty("paygate.type");
        if("dummy".equalsIgnoreCase(paygateType)) {
            return "paygate/dummy/pay";
        }
        return "paygate/alipay/alipayapi";
    }
    /**
     * 创建支付宝的付款信息对象
     * @param order
     */
    private PayInfo createPayInfo(Order order,Ordership ordership) {
        if(order==null || ordership==null){
            throw new NullPointerException("参数不能为空！请求非法！");
        }
        PayInfo payInfo = new PayInfo();
        payInfo.setWIDseller_email(ordership.getPhone());
//		String debug = SystemManager.getInstance().get("system_debug");
        String www = SystemManager.getInstance().getSystemSetting().getWww();
        /**
         * 解决由于本地和线上正式环境提交相同的商户订单号导致支付宝出现TRADE_DATA_MATCH_ERROR错误的问题。
         * 本地提交的商户订单号前缀是test开头，正式环境提交的就是纯粹的支付订单号
         */
        if(www.startsWith("http://127.0.0.1") || www.startsWith("http://localhost")){
            payInfo.setWIDout_trade_no(order.getOrderpayID());
        }else{
            payInfo.setWIDout_trade_no(order.getOrderpayID());
        }
        payInfo.setWIDsubject(order.getProductName());
        payInfo.setWIDprice(Double.valueOf(order.getPtotal()));
        payInfo.setWIDbody(order.getRemark());
//		payInfo.setShow_url(SystemManager.systemSetting.getWww()+"/product/"+payInfo.getWIDout_trade_no()+".html");
        payInfo.setShow_url(SystemManager.getInstance().getSystemSetting().getWww()+"/order/orderInfo.html?id="+order.getId());
        payInfo.setWIDreceive_name(ordership.getShipname());
        payInfo.setWIDreceive_address(ordership.getShipaddress());
        payInfo.setWIDreceive_zip(ordership.getZip());
        payInfo.setWIDreceive_phone(ordership.getTel());
        payInfo.setWIDreceive_mobile(ordership.getPhone());
        payInfo.setWIDsubject(order.getRemark());
        payInfo.setLogistics_fee(Double.valueOf(order.getFee()));
        payInfo.setLogistics_type(order.getExpressCode());
        logger.debug(payInfo.toString());
        return payInfo;
    }


    @RequestMapping("refreshPage")
    @ResponseBody
    public String refreshPage(@ModelAttribute("e")String e) throws IOException {
        String orderId = RequestHolder.getRequest().getParameter("orderId");
        Orderpay orderpay = new Orderpay();
        orderpay.setId(orderId);
        Orderpay result = orderpayService.selectOne(orderpay);
        String status = result.getPaystatus();
        ResponseUtil responseUtil = new ResponseUtil();
        if ("y".equals(status)){
            responseUtil.setSuccess();
            responseUtil.setMsg("支付成功");
        } else {
            responseUtil.setFailed();
            responseUtil.setMsg("未支付");
        }
        return responseUtil.toJsonStr();
    }

    @RequestMapping("toSuccess")
    public String toSuccess(@ModelAttribute("e")String e) throws IOException {
        return notification;
    }

    @RequestMapping("alipayResult")
    @ResponseBody
    public String alipayResult(HttpServletResponse response, HttpServletRequest request){
        /**
         * 处理支付宝回调逻辑, 大致和微信回调相同
         */
        String orderId = request.getParameter("out_trade_no");
        String trade_status = request.getParameter("trade_status");
        String trade_no = request.getParameter("trade_no");
//        Orderpay orderpay = new Orderpay();
//        orderpay.setId(orderId);
//        orderpay.setPaystatus(net.jeeshop.services.common.Order.order_paystatus_y);
        orderService.alipayNotify(trade_status, null, orderId, trade_no);
//        orderpayService.update(orderpay);
        return null;
    }

    @RequestMapping("resultPay")
    public String resultPay(HttpServletResponse response, HttpServletRequest request, @ModelAttribute("e")String e) {
        //接受微信返回的信息
        InputStream inputStream = null;
        BufferedReader reader = null;
        OutputStream outputStream = null;
        PrintWriter printWriter = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Overall.coding));
            StringBuilder stringBuilder = new StringBuilder();
            String str;
            while ((str = reader.readLine()) != null){
                stringBuilder.append(str);
            }
            //对微信返回的xml信息做解析
            WXPayResult wxPayResult = WXPayResultHandle.handleResult(stringBuilder.toString());
            String trade_status = "";
            if(StringUtils.equalsIgnoreCase("SUCCESS",wxPayResult.getResult_code())){
                trade_status = "WAIT_SELLER_SEND_GOODS";
            }
            /**
             *  @param trade_status 交易状态
             * @param refund_status	退款状态
             * @param out_trade_no 商户订单号
             * @param trade_no 微信交易号
             */
            orderService.wxNotify(trade_status,null,wxPayResult.getOut_trade_no(),wxPayResult.getTransaction_id());
            //给微信发送通知, 关闭此次支付流程
            response.reset();
            response.setContentType("text/html;charset=UTF-8");
            printWriter = response.getWriter();
            printWriter.write(ConstantPool.RESULT_OK);
            printWriter.flush();
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            try {
                if (printWriter != null) printWriter.close();
                if (outputStream != null) outputStream.close();
                if (reader != null) reader.close();
                if (reader != null) inputStream.close();
            } catch (IOException e1) {}
        }
        return null;
    }

    @RequestMapping("towxPay")
    public String towxPay(@ModelAttribute("e")String e) throws IOException {
        HttpServletRequest request = RequestHolder.getRequest();
        String code = request.getParameter("code");
        //订单号
        String orderId = request.getParameter("orderId");
        //订单名称
        String name = new String(request.getParameter("name").getBytes("iso-8859-1"), "utf-8");
        //订单总额
        String money = request.getParameter("money");
        //快递费用
        String courierMoney = request.getParameter("courierMoney");
        if (StringUtils.isEmpty(money)){
            money = "0";
        }
        if (StringUtils.isEmpty(courierMoney)){
            courierMoney = "0";
        }
        String monry_ = String.valueOf(Double.parseDouble(money) + Double.parseDouble(courierMoney));
        RequestHolder.getRequest().setAttribute("courierMoney", courierMoney);
        RequestHolder.getRequest().setAttribute("orderId", orderId);
        RequestHolder.getRequest().setAttribute("name", name);
        RequestHolder.getRequest().setAttribute("money", monry_);
        RequestHolder.getRequest().setAttribute("code", code);
        return wxpay;
    }

    @RequestMapping("wxPayCode")
    @ResponseBody
    public String wxPayCode(HttpServletResponse resp, @ModelAttribute("e") String e) throws IOException {
        String code = RequestHolder.getRequest().getParameter("code");
        new QrcodeUtil().encoderQRCoder(code, resp);
        return "";
    }

    @RequestMapping("wxPay")
    @ResponseBody
    public String wxPay(@ModelAttribute("e")String e) throws IOException {
        HttpServletRequest request = RequestHolder.getRequest();
        String name = request.getParameter("name");
        String courierMoney = request.getParameter("courierMoney");
        String money = request.getParameter("money");
        String orderId = request.getParameter("orderId");
        if (StringUtils.isEmpty(money)){
            money = "0";
        }
        if (StringUtils.isEmpty(courierMoney)){
            courierMoney = "0";
        }
        //模拟
        double monry_ = Double.parseDouble(money) + Double.parseDouble(courierMoney);
        //微信默认单位为 分
        monry_ *= 100;
        int m = (int) monry_;
        String monryValue = String.valueOf(m);
        //32位随机字符串
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.substring(6);
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        parameters.put("body", name);
        parameters.put("trade_type", "NATIVE");
        parameters.put("mch_id", OverallConfig.wx_mch_id);
        parameters.put("sign_type", "MD5");
        parameters.put("nonce_str", uuid);
        parameters.put("fee_type", "CNY");
        parameters.put("device_info", "WEB");
        parameters.put("out_trade_no", orderId);
        parameters.put("total_fee", monryValue);
        parameters.put("appid", OverallConfig.wx_appid);
        parameters.put("notify_url", OverallConfig.WEB_HTTP + "/paygate/resultPay");
        parameters.put("spbill_create_ip", "122.114.186.13");
        String reqBody = "<xml>"
                + "<body>"+name+"</body>"
                + "<trade_type>NATIVE</trade_type>"
                + "<mch_id>" + OverallConfig.wx_mch_id + "</mch_id>"
                + "<sign_type>MD5</sign_type>"
                + "<nonce_str>"+uuid+"</nonce_str>"
                + "<detail />"
                + "<fee_type>CNY</fee_type>"
                + "<device_info>WEB</device_info>"
                + "<out_trade_no>"+orderId+"</out_trade_no>"
                + "<total_fee>"+monryValue+"</total_fee>"
                + "<appid>"+OverallConfig.wx_appid+"</appid>"
                + "<notify_url>"+OverallConfig.WEB_HTTP+"/paygate/resultPay</notify_url>"
                + "<sign>"+WXSign.sign(parameters)+"</sign>"
                + "<spbill_create_ip>122.114.186.13</spbill_create_ip>"
                + "</xml>";
        IPay<String, String> iPay = PayFactory.create(PayFactory.PayType.WX_PAY);
        String wxCode = iPay.pay(reqBody);
        //这里return 微信的二维码连接
        if (wxCode == null)
            return "";
        return wxCode;
    }

    @RequestMapping("dummyPay")
    @ResponseBody
    public String dummyPay(String orderId) throws IOException {
//        orderService.alipayNotify("WAIT_SELLER_SEND_GOODS",null,orderId,String.valueOf(System.nanoTime()));
        return "{\"success\":1}";
    }

    @RequestMapping("toAliPay")
    public String toAliPay(HttpServletRequest request, String orderId) throws IOException {
        request.setAttribute("orderId", (String)request.getParameter("orderId"));
        request.setAttribute("name", new String(((String)request.getParameter("name")).getBytes("ISO8859-1"), "UTF-8"));
        String money = (String)request.getParameter("money");
        String courierMoney = (String)request.getParameter("courierMoney");
        if (StringUtils.isEmpty(money)){
            money = "0";
        }
        if (StringUtils.isEmpty(courierMoney)){
            courierMoney = "0";
        }
        double monry = Double.parseDouble(money) + Double.parseDouble(courierMoney);
        String monry_ = String.valueOf(monry);
        request.setAttribute("money", monry_);
        return alipay;
    }
}
